<template>
  <view v-if="programs" class="program-list" :class="{ 'tab-bar-sticky': tabBarSticky }">
    <view class="list-tab-bar" :class="{ 'active-tab-extra': activeTabExtra }">
      <view v-if="groups?.length" class="list-tabs" :style="tabBarStyle">
        <scroll-view
          class="scroll-view"
          scroll-x
          scroll-with-animation
          show-scrollbar="false"
          :scroll-into-view="scrollIntoView"
          style="white-space: nowrap"
          :scroll-left="scrollLeft"
        >
          <view
            v-for="(group, index) in groups"
            class="list-tab"
            :id="group.key"
            :key="group.key"
            :class="{ active: activeGroupKey === group.key, disabled, 'plain-disabled': plainDisabled }"
            @click="setActiveGroup(group, index)"
          >
            <TrackButton :track-id="'click_tab'" :type="TrackType.ApplianceDetail" :track-data="trackData">
              <text>{{ group.name }}</text>
            </TrackButton>
          </view>
        </scroll-view>
      </view>
      <view class="tabs-extra">
        <slot name="tabs-extra"></slot>
      </view>
    </view>

    <view class="list-body" v-if="programList.length > 0">
      <view class="list-grid">
        <view
          v-for="program in programList"
          :key="program.key"
          class="program-item"
          hover-class="hovering"
          :class="{ active: isCurrent(program), disabled, 'plain-disabled': plainDisabled }"
          @click="onProgramSelect(program)"
        >
          <view class="name" :class="{disabled:(program as ApplianceProgram.LocalProgramType).isNullProgram}">{{
            customNameGetter?.(program.key, program.name, isCurrent(program)) || program.name
          }}</view>
          <view v-if="isCurrent(program) && activeTips" class="tips">{{ activeTips }}</view>
          <view v-if="(program as ApplianceProgram.LocalProgramType).isLocalLeft && isShowLocal" class="local-icon">{{
            $t('Dishwasher.Sui.ProgramList.LocalLeft.Text')
          }}</view>
          <view v-if="(program as ApplianceProgram.LocalProgramType).isLocalRight && isShowLocal" class="local-icon">{{
            $t('Dishwasher.Sui.ProgramList.LocalRight.Text')
          }}</view>
        </view>
      </view>
    </view>
    <view v-if="programList.length === 0 && activeGroupKey === 'Program.Favorite'" class="favorite-empty">
      <view class="favorite-empty-des">{{ $t('ApplianceDetail.FavoriteList.None.Tips.Text') }}</view>
      <view v-if="!hideAddFavorite" class="add-favorite" @click="addFavorite">{{
        $t('ApplianceDetail.FavoriteList.None.Button.Text')
      }}</view>
    </view>
  </view>
</template>

<script setup lang="ts">
import type { ApplianceProgram } from '@/api/appliance'
import { safeTrack } from '@/dataReport/dataReportUtil'
import type { CSSProperties } from 'vue'
import { trackEvent, TrackType } from '../../../dataReport/tracks'

export type CustomProgramNameGetter = (programKey: string, programName: string, isCurrent: boolean) => string

const props = withDefaults(
  defineProps<{
    disabled?: boolean // 完全禁用操作
    plainDisabled?: boolean // 仅样式禁用 仍然触发事件
    // Tab
    groups?: ApplianceProgram.Group[] | null
    activeGroupKey?: string
    tabBarSticky?: boolean
    tabBarStyle?: CSSProperties
    //是否需要显示本地程序
    isShowLocal?: boolean
    // 是否隐藏[添加收藏]入口
    hideAddFavorite?: boolean
    // 是否启动Tab右侧自定义区域
    activeTabExtra?: boolean
    // Programs
    programs: (ApplianceProgram.Scope | ApplianceProgram.LocalProgramType)[]
    activeKey: string
    activeTips: string | null
    customNameGetter?: CustomProgramNameGetter // 自定义程序名称
  }>(),
  {}
)
const trackData = ref<{ tab_name: string }>({ tab_name: '' })
const scrollIntoView = ref('')
const scrollLeft = ref(0)
const emit = defineEmits<{
  (e: 'group-select', group: ApplianceProgram.Group): void
  (e: 'select', program: ApplianceProgram.Scope): void
  (e: 'add-favorite', selectedFavoriteVisible: boolean): void
}>()

const programList = computed(() => {
  if (props.groups) {
    nextTick(() => (scrollIntoView.value = props.activeGroupKey as string))
    return props.groups.find((group) => group.key === props.activeGroupKey)?.programs || []
  }
  return props.programs
})

function isCurrent(program: ApplianceProgram.Scope) {
  return props.activeKey === program.key
}

function setActiveGroup(group: ApplianceProgram.Group, index: number) {
  trackData.value = {
    tab_name: group.key,
  }
  nextTick(() => {
    scrollIntoView.value = group.key
    scrollLeft.value = index * 100
  })
  emit('group-select', group)
}
function onProgramSelect(program: ApplianceProgram.Scope) {
  program.trackName = props.customNameGetter?.(program.key, program.name, isCurrent(program)) || program.name
  safeTrack(() => {
    trackEvent(
      'before_select_program',
      {
        program_key: program.key,
        program_name: program.trackName,
      },
      TrackType.ApplianceDetail,
      'Appliance.Detail.Select.Program'
    )
  })

  if (isCurrent(program) || (program as ApplianceProgram.LocalProgramType).isNullProgram) return
  emit('select', program)
}
function addFavorite() {
  emit('add-favorite', true)
}
</script>

<style lang="less">
:deep(::-webkit-scrollbar) {
  display: none;
}
.active-tab-extra {
  .list-tabs {
    width: calc(100% - 188rpx) !important;
  }
  .tabs-extra {
    width: 188rpx;
    padding-right: 32rpx;
    text-align: right;
  }
}
.program-list {
  position: relative;
  transition: background-color 0.3s ease;
  &.tab-bar-sticky {
    height: 100%;
    background-color: #ffffff;
    .list-tab-bar {
      position: sticky;
      top: 0;
      z-index: 1;
      background-color: #ffffff;
    }
  }
  &:not(.tab-bar-sticky) {
    display: flex;
    flex-flow: column nowrap;
    overflow: hidden;
    height: 100%;
    .list-tab-bar {
      flex-shrink: 0;
    }
    .list-body {
      flex: 1;
      overflow: auto;
    }
  }
  .list-tab-bar {
    transition: background-color 0.3s ease;
  }

  .list-tab-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
  }

  .tabs-extra {
    font-weight: 500;
    font-size: 28rpx;
    line-height: 40rpx;
    color: var(--primary-color);
    white-space: nowrap;
    flex-shrink: 0;
    margin-top: 10rpx;
  }
  .list-tabs {
    padding: 12rpx 32rpx 0;
    overflow: auto;
    flex-grow: 1;
    transition: flex-grow 0.3s ease;
    width: 100%;
  }
  .list-tab {
    font-weight: 500;
    font-size: 32rpx;
    line-height: 40rpx;
    color: var(--dark-color);
    opacity: 0.6;
    padding: 8rpx 0;
    position: relative;
    white-space: nowrap;
    display: inline-block;
    &.active {
      opacity: 1;
      &::after {
        content: '';
        display: block;
        position: absolute;
        left: 50%;
        bottom: 0;
        width: 20rpx;
        height: 4rpx;
        background-color: var(--dark-color);
        transform: translateX(-50%);
      }
    }
    &.plain-disabled,
    &.disabled {
      filter: opacity(0.6);
    }
    &.disabled {
      pointer-events: none;
    }
    + .list-tab {
      margin-left: 48rpx;
    }
  }
  .list-tabs + .list-body {
    padding-top: 12rpx;
  }
  .list-grid {
    display: grid;
    grid-template-columns: repeat(2, calc(50% - 6rpx));
    grid-column: 2;
    gap: 12rpx;
    padding: 24rpx 32rpx;
    width: 100%;
    box-sizing: border-box;
  }
  .program-item {
    font-weight: 600;
    font-size: 40rpx;
    height: 108rpx;
    padding: 0 34rpx;
    box-sizing: border-box;
    color: var(--dark-color);
    background-color: #f4f4f6;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-flow: column nowrap;
    position: relative;
    &.hovering {
      filter: brightness(0.95);
    }
    &.active {
      color: var(--primary-color);
    }
    &.plain-disabled,
    &.disabled {
      filter: opacity(0.6);
    }
    &.disabled {
      pointer-events: none;
    }
    .ellipsis() {
      width: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .name {
      line-height: 40rpx;
      text-align: center;
      .ellipsis();
      &.disabled {
        filter: opacity(0.3);
        pointer-events: none;
      }
    }
    .tips {
      font-weight: 600;
      font-size: 32rpx;
      line-height: 40rpx;
      margin-top: 4rpx;
      text-align: center;
      .ellipsis();
    }
    .local-icon {
      font-family: PingFang SC;
      font-style: normal;
      height: 32rpx;
      text-align: center;
      line-height: 32rpx;
      background-color: var(--primary-color);
      color: #fff;
      font-weight: 600;
      font-size: 20rpx;
      position: absolute;
      top: -6rpx;
      left: -6rpx;
      padding: 0 4rpx;
    }
  }
  .favorite-empty {
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    .favorite-empty-des {
      margin-top: 20%;
      font-weight: 400;
      font-size: 28rpx;
      color: #000000;
      opacity: 0.6;
    }
    .add-favorite {
      width: 350rpx;
      height: 88rpx;
      text-align: center;
      line-height: 88rpx;
      color: var(--dark-color);
      font-weight: 600;
      font-size: 36rpx;
      margin-top: 24rpx;
      background-color: #f4f4f6;
    }
  }
  .scroll-view {
    width: 100%;
    display: inline-block;
    overflow: hidden;
  }
}
</style>
